package com.ruoyi.system.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.websocket.service.WebSocketMessageService;
import com.ruoyi.system.mapper.SpffVideosMapper;
import com.ruoyi.system.domain.SpffVideos;
import com.ruoyi.system.service.ISpffVideosService;

/**
 * 视频Service业务层处理
 * 
 * @author xjj
 * @date 2025-09-11
 */
@Service
public class SpffVideosServiceImpl implements ISpffVideosService 
{
    @Autowired
    private SpffVideosMapper spffVideosMapper;
    
    @Autowired
    private RedisCache redisCache;
    
    @Autowired
    private WebSocketMessageService webSocketMessageService;
    
    // Redis Key 常量 - 使用Set存储每个视频的点赞用户ID
    private static final String VIDEO_LIKE_SET_KEY = "video:likes:";
    private static final String VIDEO_COLLECT_SET_KEY = "video:collects:";

    /**
     * 查询视频 - 包含当前用户点赞状态
     * 
     * @param id 视频主键
     * @return 视频
     */
    @Override
    public SpffVideos selectSpffVideosById(Long id)
    {
        SpffVideos video = spffVideosMapper.selectSpffVideosById(id);
        if (video != null) {
            // 设置当前用户是否已点赞
            setVideoLikeStatus(video, getCurrentUserId());
        }
        return video;
    }

    /**
     * 查询视频列表 - 首页列表不设置点赞状态（性能优化）
     * 
     * @param spffVideos 视频
     * @return 视频
     */
    @Override
    public List<SpffVideos> selectSpffVideosList(SpffVideos spffVideos)
    {
        List<SpffVideos> videoList = spffVideosMapper.selectSpffVideosList(spffVideos);
        // 首页列表不设置点赞状态，减少Redis查询，提高性能
        return videoList;
    }

    /**
     * 新增视频
     * 
     * @param spffVideos 视频
     * @return 结果
     */
    @Override
    public int insertSpffVideos(SpffVideos spffVideos)
    {
        return spffVideosMapper.insertSpffVideos(spffVideos);
    }

    /**
     * 修改视频
     * 
     * @param spffVideos 视频
     * @return 结果
     */
    @Override
    public int updateSpffVideos(SpffVideos spffVideos)
    {
        return spffVideosMapper.updateSpffVideos(spffVideos);
    }

    /**
     * 批量删除视频
     * 
     * @param ids 需要删除的视频主键
     * @return 结果
     */
    @Override
    public int deleteSpffVideosByIds(Long[] ids)
    {
        return spffVideosMapper.deleteSpffVideosByIds(ids);
    }

    /**
     * 删除视频信息
     * 
     * @param id 视频主键
     * @return 结果
     */
    @Override
    public int deleteSpffVideosById(Long id)
    {
        return spffVideosMapper.deleteSpffVideosById(id);
    }
    
    /**
     * 点赞或取消点赞视频
     * 
     * @param videoId 视频ID
     * @param userId 用户ID
     * @return 操作结果：1-点赞成功，0-取消点赞成功
     */
    @Transactional
    public int toggleLike(Long videoId, Long userId) {
        String likeSetKey = VIDEO_LIKE_SET_KEY + videoId;
        String userIdStr = userId.toString();
        
        // 直接使用Redis Template操作Set
        @SuppressWarnings("unchecked")
        org.springframework.data.redis.core.SetOperations<String, String> setOps = 
            (org.springframework.data.redis.core.SetOperations<String, String>) redisCache.redisTemplate.opsForSet();
        
        // 检查用户是否已经点赞
        Boolean isMemberResult = setOps.isMember(likeSetKey, userIdStr);
        boolean isLiked = isMemberResult != null && isMemberResult;
        
        System.out.println("视频ID: " + videoId + ", 用户ID: " + userId + ", 当前点赞状态: " + isLiked);
        
        try {
            if (isLiked) {
                // 已点赞，执行取消点赞
                // 先更新数据库，再更新Redis
                int dbResult = spffVideosMapper.decrementLikeCount(videoId);
                if (dbResult > 0) {
                    setOps.remove(likeSetKey, userIdStr);
                    System.out.println("执行取消点赞成功");
                    return 0; // 取消点赞
                } else {
                    throw new RuntimeException("数据库更新失败");
                }
            } else {
                // 未点赞，执行点赞
                // 先更新数据库，再更新Redis
                int dbResult = spffVideosMapper.incrementLikeCount(videoId);
                if (dbResult > 0) {
                    setOps.add(likeSetKey, userIdStr);
                    System.out.println("执行点赞成功");
                    
                    // 发送点赞通知
                    try {
                        String userName = com.ruoyi.common.utils.SecurityUtils.getUsername();
                        webSocketMessageService.sendLikeNotification(videoId, userId, userName);
                    } catch (Exception e) {
                        System.err.println("发送点赞通知失败：" + e.getMessage());
                    }
                    
                    return 1; // 点赞成功
                } else {
                    throw new RuntimeException("数据库更新失败");
                }
            }
        } catch (Exception e) {
            System.err.println("点赞操作失败: " + e.getMessage());
            throw e; // 让事务回滚
        }
    }
    
    /**
     * 检查用户是否已点赞视频
     * 
     * @param videoId 视频ID
     * @param userId 用户ID
     * @return true-已点赞，false-未点赞
     */
    public boolean isUserLiked(Long videoId, Long userId) {
        if (userId == null) {
            return false;
        }
        String likeSetKey = VIDEO_LIKE_SET_KEY + videoId;
        String userIdStr = userId.toString();
        
        // 直接使用Redis Template检查Set成员
        @SuppressWarnings("unchecked")
        org.springframework.data.redis.core.SetOperations<String, String> setOps = 
            (org.springframework.data.redis.core.SetOperations<String, String>) redisCache.redisTemplate.opsForSet();
        
        Boolean isMemberResult = setOps.isMember(likeSetKey, userIdStr);
        return isMemberResult != null && isMemberResult;
    }
    
    /**
     * 设置视频的点赞状态
     * 
     * @param video 视频对象
     * @param userId 当前用户ID
     */
    private void setVideoLikeStatus(SpffVideos video, Long userId) {
        if (video != null) {
            video.setIsLike(isUserLiked(video.getId(), userId));
            video.setIsCollect(isUserCollected(video.getId(), userId));
        }
    }
    
    /**
     * 收藏或取消收藏视频
     * 
     * @param videoId 视频ID
     * @param userId 用户ID
     * @return 操作结果：1-收藏成功，0-取消收藏成功
     */
    @Transactional
    public int toggleCollect(Long videoId, Long userId) {
        String collectSetKey = VIDEO_COLLECT_SET_KEY + videoId;
        String userIdStr = userId.toString();
        
        // 直接使用Redis Template操作Set
        @SuppressWarnings("unchecked")
        org.springframework.data.redis.core.SetOperations<String, String> setOps = 
            (org.springframework.data.redis.core.SetOperations<String, String>) redisCache.redisTemplate.opsForSet();
        
        // 检查用户是否已经收藏
        Boolean isMemberResult = setOps.isMember(collectSetKey, userIdStr);
        boolean isCollected = isMemberResult != null && isMemberResult;
        
        System.out.println("视频ID: " + videoId + ", 用户ID: " + userId + ", 当前收藏状态: " + isCollected);
        
        try {
            if (isCollected) {
                // 已收藏，执行取消收藏
                // 先更新数据库，再更新Redis
                int dbResult = spffVideosMapper.decrementCollectCount(videoId);
                if (dbResult > 0) {
                    setOps.remove(collectSetKey, userIdStr);
                    System.out.println("执行取消收藏成功");
                    return 0; // 取消收藏
                } else {
                    throw new RuntimeException("数据库更新失败");
                }
            } else {
                // 未收藏，执行收藏
                // 先更新数据库，再更新Redis
                int dbResult = spffVideosMapper.incrementCollectCount(videoId);
                if (dbResult > 0) {
                    setOps.add(collectSetKey, userIdStr);
                    System.out.println("执行收藏成功");
                    
                    // 发送收藏通知
                    try {
                        String userName = com.ruoyi.common.utils.SecurityUtils.getUsername();
                        webSocketMessageService.sendCollectNotification(videoId, userId, userName);
                    } catch (Exception e) {
                        System.err.println("发送收藏通知失败：" + e.getMessage());
                    }
                    
                    return 1; // 收藏成功
                } else {
                    throw new RuntimeException("数据库更新失败");
                }
            }
        } catch (Exception e) {
            System.err.println("收藏操作失败: " + e.getMessage());
            throw e; // 让事务回滚
        }
    }
    
    /**
     * 检查用户是否已收藏视频
     * 
     * @param videoId 视频ID
     * @param userId 用户ID
     * @return true-已收藏，false-未收藏
     */
    public boolean isUserCollected(Long videoId, Long userId) {
        if (userId == null) {
            return false;
        }
        String collectSetKey = VIDEO_COLLECT_SET_KEY + videoId;
        String userIdStr = userId.toString();
        
        @SuppressWarnings("unchecked")
        org.springframework.data.redis.core.SetOperations<String, String> setOps = 
            (org.springframework.data.redis.core.SetOperations<String, String>) redisCache.redisTemplate.opsForSet();
        
        Boolean isMemberResult = setOps.isMember(collectSetKey, userIdStr);
        return isMemberResult != null && isMemberResult;
    }

    /**
     * 获取当前登录用户ID
     * 
     * @return 用户ID
     */
    private Long getCurrentUserId() {
        try {
            return com.ruoyi.common.utils.SecurityUtils.getUserId();
        } catch (Exception e) {
            return null; // 未登录用户返回null
        }
    }
}
